part of "../shelf.dart";

/// 将一个[Table]转化成标准的Restful Router
/// 其中指定如何处理post和put的部分逻辑即可
extension RestfulRouter<T> on TableGeneral<T> {
  /// 将数据库转化为一个标准的RESTful Router
  /// 需要用户登录
  Router toRestfulRouter({
    /// 将请求体中的数据转换为创建所需要的参数
    /// TODO：这里和Table内置的详细的getField有些冲突，比如说table内部的field就不会显示正确的报错信息（会和Handler冲突）
    Json Function(Json body)? postArgs,

    /// 找到对象后，结合请求体直接修改对象
    required void Function(Json body, T object) putModify,
  }) =>
      Router()
        // 1. 获取所有数据
        ..get("/", (Request request) async {
          // 如果不是ForUser的table，暂时可以报错
          if (this is TableForUser<T>) {
            // 找到所有数据并返回
            List<T> all = await (this as TableForUser<T>).findFor(request.id);
            return responseOK(all);
          } else {
            throw BugDev("获取所有只对TableForUser类有效");
          }
        })
        // 2. 获取单个数据
        ..get("/<id>", (Request request, String id) async {
          // 根据id寻找并返回，否则返回404
          final T? found = await find(int.parse(id));
          if (found == null) return response(404, "无法根据id[$id]找到数据");
          return responseOK(found);
        })
        // 3. 创建新数据
        ..post("/", (Request request) async {
          // 把请求中的body转换为可以直接用来创建新数据的map
          final Json args =
              postArgs != null ? postArgs(request.body) : request.body;
          // 给参数加上用户id
          args["user_id"] = request.id;

          final T object = await create(args);
          // 将创建的对象返回客户端
          return responseOK(object);
        })

        // 4. 更新数据
        ..put("/<id>", (Request request, String id) async {
          // 根据id找到对象
          final T? found = await find(int.parse(id));
          if (found == null) return response(404, "无法根据id[$id]找到数据");
          // 将对象和body传入转化函数，生成一个新的对象
          putModify(request.body, found);
          // 保存修改后，将新对象返回给客户端
          await update(found);
          return responseOK(found);
        })

        // 5. 删除数据
        ..delete("/<id>", (Request request, String id) async {
          // 先确保对象存在
          final T? found = await find(int.parse(id));
          if (found == null) return response(404, "无法根据id[$id]找到数据");

          // 执行删除逻辑
          await delete(int.parse(id));
          return response(204);
        });
}
